<?php
/**
 * 支付宝支付接口
 */
namespace V3\Controller;

use Think\Controller;

class AlipayController extends ApiCommonController{
	
	private $conf = array(
		'notify_url'	=>	'http://mov30.weixinzjit.com/V3/Alipay/notify',
		'return_url'	=>	'http://mov30.weixinzjit.com/V3/Alipay/returnurl',
		'seller_email'	=>	'taixia@51dy.ren',
		'partner'	=>	'2088121587691510', 
		'key'		=>	'poyzgkrfmhqp023yvo7ftm3n09mdbs1c',
		'privateKey' => '/home/mov30.weixinzjit.com/Moviedate/V3/Controller/rsa_private_key.pem',
		'publicKey' => '/home/mov30.weixinzjit.com/Moviedate/V3/Controller/rsa_public_key.pem',
	);	
	
	/**
	* 获取支付参数
	* @return
	*/
	public function getParm(){   
		$payid = $_GET['payid'];
		$payid = '123456789';
		if(empty($payid)){
			exit(json_encode(array('status'=>"0",'info'=>'ordercode id empty')));
		}
		$orderinfo = $this->getOrderInfo($payid);
		if(!$orderinfo){
			exit(json_encode(array('status'=>"0",'info'=>'get Order Error , Maybe you give the wrong Ordercode')));
		} 
		$parameter = array(
			'service' => 'mobile.securitypay.pay',
			'partner' => $this->conf['partner'],
			'_input_charset' => 'utf-8',
			'notify_url' => $this->conf['notify_url'],
			'seller_id' => $this->conf['seller_email'],
			'payment_type' => 1,
			'out_trade_no' => $payid, 
			'subject' => $orderinfo['title'],
			'body' => $orderinfo['title'],
			//'total_fee' => $orderinfo['money'],   
			'total_fee' => 0.01,   //测试的时候使用，更新生产的话把这行删除， 把上行注释去掉
		);
		$pp=$this->paraFilter($parameter);
		$ppa =$this->argSort($pp);
		$parameter['sign'] = $this->rsaSign($this->createLinkstring($ppa),$this->conf['privateKey']);
		$parameter['sign_type'] = 'RSA';
		$aa=$this->createLinkstringUrlencode($parameter);
		echo json_encode(array('status'=>"1",'info'=>'Success','data'=>$aa));
		exit();
	}

	/**
	 * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
	 * @param $para 需要拼接的数组
	 * return 拼接完成以后的字符串
	 */
	function createLinkstring($para) {
		$arg  = "";
		while (list ($key, $val) = each ($para)) {
			$arg.=$key."=".$val."&";
		}
		//去掉最后一个&字符
		$arg = substr($arg,0,count($arg)-2);

		//如果存在转义字符，那么去掉转义
		if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}

		return $arg;
	}
	/**
	 * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串，并对字符串做urlencode编码
	 * @param $para 需要拼接的数组
	 * return 拼接完成以后的字符串
	 */
	function createLinkstringUrlencode($para) {
		$arg  = "";
		while (list ($key, $val) = each ($para)) {
			$arg.=$key."=".urlencode($val)."&";
		}
		//去掉最后一个&字符
		$arg = substr($arg,0,count($arg)-2);

		//如果存在转义字符，那么去掉转义
		if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}

		return $arg;
	}
	/**
	 * 除去数组中的空值和签名参数
	 * @param $para 签名参数组
	 * return 去掉空值与签名参数后的新签名参数组
	 */
	function paraFilter($para) {
		$para_filter = array();
		while (list ($key, $val) = each ($para)) {
			if($key == "sign" || $key == "sign_type" || $val == "")continue;
			else	$para_filter[$key] = $para[$key];
		}
		return $para_filter;
	}
	/**
	 * 对数组排序
	 * @param $para 排序前的数组
	 * return 排序后的数组
	 */
	function argSort($para) {
		ksort($para);
		reset($para);
		return $para;
	}
	
	/**
	 * RSA签名
	 * @param $data 待签名数据
	 * @param $private_key_path 商户私钥文件路径
	 * return 签名结果
	 */
	function rsaSign($data, $private_key_path) {
		$priKey = file_get_contents($private_key_path);
		$res = openssl_get_privatekey($priKey);
		openssl_sign($data, $sign, $res);
		openssl_free_key($res);
		//base64编码
		$sign = base64_encode($sign);
		return $sign;
	}
	
	public function getSign($parm){
		$privateKey = openssl_get_privatekey(file_get_contents($this->conf['privateKey']));
		$data = $parm; 
		$sign = '';
		openssl_sign($data, $sign, $privateKey, OPENSSL_ALGO_SHA1); 
		return base64_encode($sign);
		exit();
	}
	
	public function ArrayToString($arr){
		$parm = array();
		foreach($arr as $k=>$v){
			$parm[] = $k.'="'.$v.'"';
		}
		$parms = implode('&',$parm);
		return $parms;
	}
	
	/**
	* 待完善 支付完成通知接口
	* @return
	*/
	public function notify(){  
		$this->_log($_POST);
		$verify_result = $this->verifyNotify();
		$this->_log($verify_result);
		if($verify_result) { 
			$trade_status = $_POST['trade_status'];
			if($trade_status!='TRADE_SUCCESS'){
				echo "fail"; exit();
			}
			$payid = $_POST['out_trade_no'];
			$buyer_email = $_POST['buyer_email'];
			$buyer_id = $_POST['buyer_id'];
			$rs = $this->updateOrderStatus($payid,$buyer_email,$buyer_id);
			if($rs){
				echo "success";
			}else{
				echo "fail";
			}
		}
		else {
		    echo "fail";
		}
		exit();
	}
	
	function verifyNotify(){
		if(empty($_POST)) {//判断POST来的数组是否为空
			return false;
		}
		else {
			//生成签名结果
			$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
			return $isSign;
		}
	}
	
    /**
     * 获取返回时的签名验证结果
     * @param $para_temp 通知返回来的参数数组
     * @param $sign 返回的签名结果
     * @return 签名验证结果
     */
	function getSignVeryfy($para_temp, $sign) {
		//除去待签名参数数组中的空值和签名参数
		$para_filter = $this->paraFilter($para_temp); 
		//对待签名参数数组排序
		$para_sort = $this->argSort($para_filter); 
		//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
		$isSgin = false;
		$isSgin = $this->rsaVerify($this->createLinkstring($para_sort), trim($this->conf['publicKey']), $sign);
		return $isSgin;
	}

	/**
	 * RSA验签
	 * @param $data 待签名数据
	 * @param $ali_public_key_path 支付宝的公钥文件路径
	 * @param $sign 要校对的的签名结果
	 * return 验证结果
	 */
	function rsaVerify($data, $ali_public_key_path, $sign)  {
		$pubKey = file_get_contents($ali_public_key_path);
	    $res = openssl_get_publickey($pubKey);
	    $result = (bool)openssl_verify($data, base64_decode($sign), $res);
	    openssl_free_key($res);    
	    return $result;
	}
	
	/**
	* 更新订单状态
	* @param $ordercode 订单编号
	* @param $buyer_email 支付者邮箱或者手机号码
	* @param $buyer_id 支付者ID
	* @return
	*/
	function updateOrderStatus($payid,$buyer_email,$buyer_id){
		$orders = M('Order')->where(array('pay_order_id'=>$payid))->select();
		//如果已支付  则返回成功
		foreach($orders as $order){
			if($order['pay_status']==2) continue; 
			$rs = M('Order')->save(array(	'id'=>$order['id'],
											'buyer_email'=>$buyer_email,
											'buyer_id'=>$buyer_id,
											'pay_status'=>2,
											'code_status'=>3));
		}
		return true;
	}
	
	/**
	* 获取订单数据
	* @param undefined $ordercode 
	* @return
	*/
	function getOrderInfo($payid){
		$order = M('Order')->where(array('pay_order_id'=>$payid))->select();
		if(empty($order)) return false;
		$orderinfo =  M('Orderdetial')->where(array('order_id'=>$order[0]['id']))->find();
		if(empty($orderinfo)) return false;
		$money = 0; 
		foreach($order as $od){
			$money += $od['code_money']; 
		}
		return array(
			'title'	=>	$orderinfo['product_title'],
			'money'	=>	$money
		);
	}
	
	public function _log($data){ 
		$str = $this->_tostring($data);
		$str = date('Y-m-d H:i:s',time()).'|'.$str.'
';
		$f = fopen('/home/mov30.weixinzjit.com/Public/log/ali_log.txt','a+'); 
		fwrite($f,$str);
		fclose($f); 
	}
	
	public function _tostring($obj){
		if(is_string($obj)) return $obj;
		return json_encode($obj);
	}
	
	
}